package com.bk.bookviews.service.impl;

import com.bk.bookviews.common.Constants;
import com.bk.bookviews.common.Pagination;
import com.bk.bookviews.domain.*;
import com.bk.bookviews.exception.BusinessException;
import com.bk.bookviews.exception.BusinessExceptionEnum;
import com.bk.bookviews.mapper.*;
import com.bk.bookviews.service.ScenicInfoService;
import com.bk.bookviews.util.FileUpload;
import com.bk.bookviews.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ScenicInfoServiceImpl implements ScenicInfoService {
    @Resource
    private RedisUtil redisUtil;
    @Autowired
    private ScenicInfoMapper scenicInfoMapper;
    @Autowired
    private PictureMapper pictureMapper;
    @Autowired
    private TitleScenicMapper titleScenicMapper;
    @Autowired
    private BookingOrderMapper orderMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Override
    public ScenicInfo selectScenic(Long scenicId,String token) {
        ScenicInfo scenicInfo = scenicInfoMapper.selectByPrimaryKey(scenicId);
        if(scenicInfo!=null){
            TitleScenicExample titleRoomExample = new TitleScenicExample();
            TitleScenicExample.Criteria titleRoomExampleCriteria = titleRoomExample.createCriteria();
            titleRoomExampleCriteria.andScenicIdEqualTo(scenicInfo.getScenicId());
            List<TitleScenic> titleScenics = titleScenicMapper.selectByExample(titleRoomExample);
            if (!CollectionUtils.isEmpty(titleScenics)){
                StringBuilder builder = new StringBuilder();
                for (TitleScenic titleScenic : titleScenics) {
                    builder.append(titleScenic.getTitleId()).append(",");
                }
                if (builder.length() > 1){
                    builder.deleteCharAt(builder.length()-1);
                }
                scenicInfo.setTitleId(builder.toString());
            }

            PictureExample pictureExample = new PictureExample();
            PictureExample.Criteria criteria = pictureExample.createCriteria();
            criteria.andScenicIdEqualTo(scenicId);
            criteria.andPictureStatuEqualTo(Constants.PICTURE_STATUS_NORMAL);
            List<Picture> pictures = pictureMapper.selectByExample(pictureExample);
            scenicInfo.setPictureList(pictures);

            CommentExample example = new CommentExample();
            CommentExample.Criteria criteria1 = example.createCriteria();
            criteria1.andScenicIdEqualTo(scenicId);
            List<Comment> comments = commentMapper.selectByExample(example);
            scenicInfo.setCommentList(comments);
        }
        return scenicInfo;
    }
    @Override
    public void add(ScenicInfo scenicInfo, String token) {
        scenicInfo.setScenicStatus(Constants.SCENIC_STATUS_NORMAL);
        scenicInfo.setCreateTime(new Date());
        UserInfo userInfo = (UserInfo) redisUtil.get(token);
        if (userInfo == null){
            throw new BusinessException(BusinessExceptionEnum.LOGON_FAILURE);
        }

        if (scenicInfo.getScenicPrice() == null){
            throw new BusinessException(BusinessExceptionEnum.SCENIC_PRICE_ISNULL);
        }
        scenicInfo.setCreatePerson(userInfo.getUserPhone());
        scenicInfoMapper.insertSelective(scenicInfo);
        Long scenicId = scenicInfo.getScenicId();
        String titleIds = scenicInfo.getTitleId();
        if (StringUtils.isNotBlank(titleIds)){
            String[] split = titleIds.split(",");
            List<TitleScenic> titleScenics = new ArrayList<>();
            for (String s:split) {
                TitleScenic titleScenic = new TitleScenic();
                titleScenic.setScenicId(scenicId);
                titleScenic.setTitleId(Long.parseLong(s));
                titleScenics.add(titleScenic);
            }
            if (!CollectionUtils.isEmpty(titleScenics)){
                titleScenicMapper.insertBatch(titleScenics);
            }
        }
        List<Picture> pictureList = scenicInfo.getPictureList();
        if (!CollectionUtils.isEmpty(pictureList)){
            for (Picture p : pictureList) {
                p.setScenicId(scenicId);
                p.setPictureStatu(Constants.PICTURE_STATUS_NORMAL);
            }
        }
        pictureMapper.insertBatch(pictureList);
    }

    @Override
    public String uploadFile(MultipartFile file) {
        return FileUpload.upload(file);
    }

    @Override
    public void updateScenic(ScenicInfo scenicInfo) {
        ScenicInfo scenicInfo1 = selectScenic(scenicInfo.getScenicId(),null);
        if (scenicInfo1 == null){
            throw new BusinessException(BusinessExceptionEnum.SCENIC_NOT_EXIST);
        }
        if (scenicInfo1.getScenicPrice() == null){
            throw new BusinessException(BusinessExceptionEnum.SCENIC_PRICE_ISNULL);
        }
        scenicInfoMapper.updateByPrimaryKeySelective(scenicInfo);

        TitleScenicExample example = new TitleScenicExample();
        example.createCriteria().andScenicIdEqualTo(scenicInfo.getScenicId());
        titleScenicMapper.deleteByExample(example);
        String titleIds = scenicInfo.getTitleId();
        if (StringUtils.isNotBlank(titleIds)){
            String[] split = titleIds.split(",");
            List<TitleScenic> titleScenics = new ArrayList<>();
            for (String s:split) {
                TitleScenic titleScenic = new TitleScenic();
                titleScenic.setScenicId(scenicInfo.getScenicId());
                titleScenic.setTitleId(Long.parseLong(s));
                titleScenics.add(titleScenic);
            }
            if (!CollectionUtils.isEmpty(titleScenics)){
                titleScenicMapper.insertBatch(titleScenics);
            }
        }
        // 先删除，后插入
        PictureExample pictureExample = new PictureExample();
        pictureExample.createCriteria().andScenicIdEqualTo(scenicInfo.getScenicId());
        pictureMapper.deleteByExample(pictureExample);
        List<Picture> pictureList = scenicInfo.getPictureList();
        if (!CollectionUtils.isEmpty(pictureList)){
            for (Picture p : pictureList) {
                p.setScenicId(scenicInfo.getScenicId());
                p.setPictureStatu(Constants.PICTURE_STATUS_NORMAL);
            }
        }
        pictureMapper.insertBatch(pictureList);
    }

    @Override
    public void del(ScenicInfo scenicInfo, String token) {
        ScenicInfo scenicInfo1 = selectScenic(scenicInfo.getScenicId(),null);
        if (scenicInfo1 == null){
            throw new BusinessException(BusinessExceptionEnum.SCENIC_NOT_EXIST);
        }
        if (scenicInfo1.getScenicPrice() == null){
            throw new BusinessException(BusinessExceptionEnum.SCENIC_PRICE_ISNULL);
        }
        scenicInfo.setScenicStatus("2");
        scenicInfoMapper.updateByPrimaryKeySelective(scenicInfo);
        BookingOrderExample example = new BookingOrderExample();
        BookingOrderExample.Criteria criteria = example.createCriteria();
        //查找预约状态-0-预约成功待支付 1-支付成功 并且小于等于当前当前时间的订单，并让其失效
        criteria.andScenicIdEqualTo(scenicInfo.getScenicId());
        criteria.andBookingStatusBetween("0","1");
        criteria.andBookingTimeGreaterThanOrEqualTo(new Date());
        List<BookingOrder> bookingOrders = orderMapper.selectByExample(example);
        if (bookingOrders.size()>0){
            for (BookingOrder order:
                    bookingOrders ) {
                order.setBookingStatus("3");
                orderMapper.updateByPrimaryKey(order);
            }
        }
    }
    @Override
    public Pagination selectScenicList(ScenicInfo scenicInfo) {
        ScenicInfoExample example = new ScenicInfoExample();
        ScenicInfoExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNoneBlank(scenicInfo.getScenicName())){
            criteria.andScenicNameLike("%"+scenicInfo.getScenicName()+"%");
        }
        if (StringUtils.isNotBlank(scenicInfo.getScenicArea())){
            criteria.andScenicAreaLike("%"+scenicInfo.getScenicArea()+"%");
        }
        if (StringUtils.isNotBlank(scenicInfo.getScenicLevel())){
            criteria.andScenicLevelEqualTo(scenicInfo.getScenicLevel());
        }
        if (Constants.QUERY_SOURCE.equals(scenicInfo.getSource())){
            criteria.andScenicStatusEqualTo(Constants.SCENIC_STATUS_NORMAL);
        }
        if (!Constants.QUERY_SOURCE.equals(scenicInfo.getSource()) &&
                StringUtils.isNotBlank(scenicInfo.getScenicStatus())){
            criteria.andScenicStatusEqualTo(scenicInfo.getScenicStatus());
        }
        List<ScenicInfo> scenicInfos = scenicInfoMapper.selectByExample(example);
        // 标签
        if (StringUtils.isNotBlank(scenicInfo.getTitleId())){
            // 标签id List查询条件
            String[] titleIdsSplit = scenicInfo.getTitleId().split(",");
            List<Long> titleIds = new ArrayList<Long>();
            for (String titleId : titleIdsSplit) {
                titleIds.add(Long.parseLong(titleId));
            }
            // 查询标签条件在titleIds中的room
            TitleScenicExample titleScenicExample = new TitleScenicExample();
            TitleScenicExample.Criteria titleRoomExampleCriteria = titleScenicExample.createCriteria();
            titleRoomExampleCriteria.andTitleIdIn(titleIds);
            List<TitleScenic> titleScenics = titleScenicMapper.selectByExample(titleScenicExample);
            // 根据房间id对查询结果进行分组
            Map<Long, List<TitleScenic>> scenicTitiles = titleScenics.stream().collect(Collectors.groupingBy(TitleScenic::getScenicId));
            List<Long> titleScenicIds = new ArrayList<>();
            // 查询满足所有标签条件的房间
            for (Map.Entry<Long, List<TitleScenic>> entry: scenicTitiles.entrySet()) {
                if (entry.getValue().size() == titleIdsSplit.length){
                    titleScenicIds.add(entry.getKey());
                }
            }
            // 过滤出满足所有标签条件的景点
            scenicInfos = scenicInfos.stream().filter(t -> titleScenicIds.contains(t.getScenicId())).collect(Collectors.toList());
        }

        if(!CollectionUtils.isEmpty(scenicInfos)){
            // 查询标签条件在titleIds中的scenicInfo
            List<Long> collect = scenicInfos.stream().map(ScenicInfo::getScenicId).collect(Collectors.toList());
            TitleScenicExample titleScenicExample = new TitleScenicExample();
            TitleScenicExample.Criteria titleScenicExampleCriteria = titleScenicExample.createCriteria();
            titleScenicExampleCriteria.andScenicIdIn(collect);
            List<TitleScenic> titleScenics = titleScenicMapper.selectByExample(titleScenicExample);
            if (!CollectionUtils.isEmpty(titleScenics)){
                Map<Long, List<TitleScenic>> scenicTitleList = titleScenics.stream().collect(Collectors.groupingBy(TitleScenic::getScenicId));
                for (ScenicInfo r : scenicInfos) {
                    List<TitleScenic> titleScenic1 = scenicTitleList.get(r.getScenicId());
                    if (!CollectionUtils.isEmpty(titleScenic1)){
                        StringBuilder builder = new StringBuilder();
                        for (TitleScenic titleRoom : titleScenic1) {
                            builder.append(titleRoom.getTitleId()).append(",");
                        }
                        if (builder.length() > 1){
                            builder.deleteCharAt(builder.length()-1);
                        }
                        r.setTitleId(builder.toString());
                    }
                }
            }
            PictureExample pictureExample = new PictureExample();
            PictureExample.Criteria pictureExampleCriteria = pictureExample.createCriteria();
            pictureExampleCriteria.andScenicIdIn(collect);
            pictureExampleCriteria.andPictureStatuEqualTo(Constants.PICTURE_STATUS_NORMAL);
            List<Picture> pictures = pictureMapper.selectByExample(pictureExample);
            Map<Long, List<Picture>> roomPictureList = pictures.stream().collect(Collectors.groupingBy(Picture::getScenicId));
            for (ScenicInfo r :scenicInfos) {
                r.setPictureList(roomPictureList.get(r.getScenicId()));
            }
        }
        return new Pagination(scenicInfos);
    }

}
